package com.springboot.seckill.service.impl;

import com.springboot.seckill.dataobject.ItemDO;
import com.springboot.seckill.dataobject.ItemStockDO;
import com.springboot.seckill.enums.EmPromoConstants;
import com.springboot.seckill.error.BusinessException;
import com.springboot.seckill.error.EmBusinessError;
import com.springboot.seckill.mapper.ItemDOMapper;
import com.springboot.seckill.mapper.ItemStockDOMapper;
import com.springboot.seckill.service.ItemService;
import com.springboot.seckill.service.PromoService;
import com.springboot.seckill.service.model.ItemModel;
import com.springboot.seckill.service.model.PromoModel;
import com.springboot.seckill.validator.ValidationResult;
import com.springboot.seckill.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: HuangDekai
 * @Date: 2022/3/18 9:11
 * @Version: 1.0
 * @since: jdk11
 */
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ItemDOMapper itemDOMapper;
    @Autowired
    private ItemStockDOMapper itemStockDOMapper;
    @Autowired
    private PromoService promoService;
    @Autowired
    private ValidatorImpl validator;


    /**
     * 创建商品
     *
     * @param itemModel itemModel
     * @return itemModel
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public ItemModel createItem(ItemModel itemModel) throws BusinessException {
        //校验入参
        ValidationResult result = validator.validate(itemModel);
        if (result.isHasErrors()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
        }
        //转换itemModel->dataObject
        ItemDO itemDO = convertItemDOFromItemModel(itemModel);

        //写入数据库
        itemDOMapper.insertSelective(itemDO);
        itemModel.setId(itemDO.getId());

        ItemStockDO itemStockDO = convertItemStockDOFromItemModel(itemModel);
        itemStockDOMapper.insertSelective(itemStockDO);

        //返回创建完成的实体
        return this.getItemById(itemModel.getId());
    }

    /**
     * 商品浏览列表
     *
     * @return 商品浏览列表
     */
    @Override
    public List<ItemModel> listItems() {
        List<ItemDO> itemDOList = itemDOMapper.listItem();
        return itemDOList.stream().map(
                itemDO -> {
                    ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDO.getId());
                    return this.convertItemModelFromDataObject(itemDO, itemStockDO);
                }
        ).collect(Collectors.toList());
    }

    /**
     * 通过Id查询商品详情
     *
     * @param id id
     * @return ItemModel
     */
    @Override
    public ItemModel getItemById(Integer id) {
        ItemDO itemDO = itemDOMapper.selectByPrimaryKey(id);
        if (itemDO == null) {
            return null;
        }
        //操作获取库存数量
        ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDO.getId());
        //将DataObject -> model
        ItemModel itemModel = convertItemModelFromDataObject(itemDO, itemStockDO);
        //获取活动商品信息
        PromoModel promoModel = promoService.getPromoByItemId(itemModel.getId());
        if (promoModel != null && promoModel.getStatus().intValue() != EmPromoConstants.SECKILL_STATUS_END.getValue()) {
            itemModel.setPromoModel(promoModel);
        }

        return itemModel;
    }

    /**
     * 将ItemModel转换为ItemDO
     * @param itemModel ItemModel
     * @return ItemDO
     */
    private ItemDO convertItemDOFromItemModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        ItemDO itemDO = new ItemDO();
        BeanUtils.copyProperties(itemModel, itemDO);
        return itemDO;
    }

    /**
     * 将ItemModel转换为ItemStockDO
     * @param itemModel ItemModel
     * @return ItemStock
     */
    private ItemStockDO convertItemStockDOFromItemModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        ItemStockDO itemStockDO = new ItemStockDO();
        itemStockDO.setItemId(itemModel.getId());
        itemStockDO.setStock(itemModel.getStock());
        return itemStockDO;
    }

    /**
     * 将ItemDO和ItemStockDO转换为ItemModel
     * @param itemDO ItemDO
     * @param itemStockDO ItemStockDO
     * @return ItemModel
     */
    private ItemModel convertItemModelFromDataObject(ItemDO itemDO, ItemStockDO itemStockDO) {
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(itemDO, itemModel);
        itemModel.setStock(itemStockDO.getStock());
        return itemModel;
    }

    /**
     * 库存扣减
     *
     * @param itemId 商品id
     * @param amount 商品数量
     * @return 是否扣减成功
     * @throws BusinessException 商品id不存在
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException {
        int affectedRow = itemStockDOMapper.decreaseStock(itemId, amount);
        return affectedRow > 0;
    }

    /**
     * 增加商品销量
     *
     * @param itemId 商品id
     * @param amount 增加的销量的数量
     * @throws BusinessException 商品id不存在/数量不正确
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void increaseSales(Integer itemId, Integer amount) throws BusinessException {
        itemDOMapper.increaseSales(itemId, amount);
    }
}
